package com.yuyou.fn.educational.service.impl;

import com.github.wens.framework.service.impl.SuperServiceImpl;
import com.github.wens.mybatisplus.examples.Example;
import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.common.exception.BusException;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.CriteriaUtils;
import com.yuyou.fn.common.util.Principals;
import com.yuyou.fn.common.util.TimeUtils;
import com.yuyou.fn.educational.entity.ExamPaper;
import com.yuyou.fn.educational.entity.ExamQuestion;
import com.yuyou.fn.educational.mapper.ExamPaperMapper;
import com.yuyou.fn.educational.service.*;
import com.yuyou.fn.educational.vo.ExamPaperQueryVo;
import com.yuyou.fn.educational.vo.ExamPaperQuestionsVo;
import com.yuyou.fn.educational.vo.ExamPaperSaveOrUpdateVo;
import com.yuyou.fn.educational.vo.ExamQuestionsSaveOrUpdateVo;
import com.yuyou.fn.platform.service.IAreaTeamService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 *
 * ExamPaper 表数据服务层接口实现类
 *
 */
@Service
public class ExamPaperServiceImpl extends SuperServiceImpl<ExamPaperMapper, ExamPaper,Long> implements IExamPaperService {

    @Resource
    private IExamQuestionService examQuestionService;

    @Resource
    private IAreaTeamService areaTeamService;

    @Resource
    private IBaseGradeService baseGradeService;

    @Resource
    private IBaseSubjectService baseSubjectService;

    @Resource
    private RedisTemplate<String,String> redisTemplate;

    @Resource
    private IMeasurementService measurementService;

    @Override
    public ExamPaperQuestionsVo findQuestionsOfExamPaper(Long examPaperId) {
        ExamPaper examPaper = findById(examPaperId);
        List<ExamQuestion> questions =  examQuestionService.findExamQuestionByExamPaperId(examPaperId);
        return new ExamPaperQuestionsVo(examPaper,questions );
    }

    @Transactional
    @Override
    public void saveOrUpdateExamPaperQuestions(ExamQuestionsSaveOrUpdateVo examQuestionsSaveOrUpdateVo) {
        Validate.notNull(examQuestionsSaveOrUpdateVo.getExamPaperId());
        Validate.notNull(examQuestionsSaveOrUpdateVo.getQuestions());


        int totalScore = 0 ;
        int questionNo = 1 ;


        deleteQuestion(examQuestionsSaveOrUpdateVo.getExamPaperId());

        List<ExamQuestion> examQuestions = new ArrayList<>(examQuestionsSaveOrUpdateVo.getQuestions().size());

        for(ExamQuestionsSaveOrUpdateVo.Question question : examQuestionsSaveOrUpdateVo.getQuestions() ){
            ExamQuestion examQuestion = new ExamQuestion();
            BeanUtils.copyProperties(examQuestion,question );
            examQuestion.setQuestionNo(questionNo++);

            Validate.notNull(examQuestion.getScore() ,"Invalid score");
            Validate.notNull(examQuestion.getAnswer() ,"Invalid answer");
            Validate.notNull(examQuestion.getAnswerConfig() ,"Invalid answerConfig");
            Validate.notNull(examQuestion.getBody() ,"Invalid body");

            if(examQuestion.getScore() == null || examQuestion.getScore() <= 0  ){
                throw new IllegalArgumentException("Invalid score");
            }



            examQuestion.setExamPaperId(examQuestionsSaveOrUpdateVo.getExamPaperId());
            examQuestion.setCreateTime(TimeUtils.now());
            examQuestion.setUpdateTime(TimeUtils.now());

            totalScore += examQuestion.getScore() ;

            examQuestions.add(examQuestion);


        }
        examQuestionService.insertBatch(examQuestions);
        ExamPaper examPaper = new ExamPaper();
        examPaper.setExamPaperId(examQuestionsSaveOrUpdateVo.getExamPaperId());
        examPaper.setTotalScore(totalScore);
        examPaper.setQuestionAmount(examQuestionsSaveOrUpdateVo.getQuestions().size());
        updateSelectiveById(examPaper);
    }

    private void deleteQuestion(Long examPaperId2) {
        Example<ExamQuestion> examQuestionExample = ExamQuestion.createExample();
        examQuestionExample.createCriteria().andEqualTo("examPaperId", examPaperId2);
        examQuestionService.deleteByExample(examQuestionExample);
    }

    @Override
    public Page<ExamPaper> findExamPapersByQuery(ExamPaperQueryVo examPaperQueryVo, int pageNo, int pageSize) {
        Example<ExamPaper> example = ExamPaper.createExample();
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();

        if(examPaperQueryVo.getHasQuestion() != null ){
            criteria.andGreaterThan("questionAmount" ,0 );
            examPaperQueryVo.setHasQuestion(null);
        }
        CriteriaUtils.fillCondition(criteria,examPaperQueryVo);
        return findPageByExample(example,pageNo,pageSize );
    }

    @Override
    public void saveOrUpdateExamPaper(ExamPaperSaveOrUpdateVo examPaperSaveOrUpdateVo) {

        ExamPaper examPaper = new ExamPaper();
        BeanUtils.copyProperties(examPaper, examPaperSaveOrUpdateVo);

        if (examPaper.getExamPaperId() == null) {

            Validate.notNull(examPaper.getAreaTeamId(),"Invalid areaTeamId");
            Validate.notNull(examPaper.getGradeId(),"Invalid gradeId");
            Validate.notNull(examPaper.getSubjectId(),"Invalid subjectId");
            Validate.notNull(examPaper.getTitle(),"Invalid title");
            Validate.notNull(examPaper.getTestTime(),"Invalid testTime");

            examPaper.setCreatorId(Principals.get().id);
            examPaper.setTotalScore(0);
            examPaper.setQuestionAmount(0);
            examPaper.setExamPaperNo(newNo());
            if(examPaper.getAsFlag() == null ){
                examPaper.setAsFlag(0);
            }
            examPaper.setCreateTime(TimeUtils.now());
        }

        examPaper.setUpdateTime(TimeUtils.now());
        if (examPaper.getAreaTeamId() != null) {
            examPaper.setAreaTeamName(areaTeamService.findTeamNameById(examPaper.getAreaTeamId()));
        }

        if (examPaper.getGradeId() != null) {
            examPaper.setGradeName(baseGradeService.findGradeNameById(examPaper.getGradeId()));
        }

        if (examPaper.getSubjectId() != null) {
            examPaper.setSubjectName(baseSubjectService.findGradNameById(examPaper.getSubjectId()));
        }

        if (examPaper.getExamPaperId() == null) {
            insertSelective(examPaper);
        } else {
            updateSelectiveById(examPaper);
        }


    }

    @Override
    public void delExamPaper(Long examPaperId) {
        if( measurementService.hasBindThisExamPaperId(examPaperId)) {
            throw new BusException("不能删除");
        }
        deleteQuestion(examPaperId);
        deleteById(examPaperId);

    }

    public String newNo() {
        Calendar now = Calendar.getInstance();
        int year = now.get(Calendar.YEAR);
        Long no = redisTemplate.opsForValue().increment("exam_paper_no", 1);
        return year + StringUtils.leftPad(String.valueOf(no), 6, "0");
    }
}